@page "/taskmanagement"
@rendermode InteractiveServer
@using LiteDB
@using PHMEE.Diagnosis
@using PHMEE.VibrationDataGenerator.Data
@using PHMEE.VibrationDataGenerator.Services
@using Quartz
@inject TaskConfigRepository TaskConfigRepository
@inject TaskManagementService TaskManagementService
@inject ChannelConfigRepository ChannelRepository

<PageTitle>TasksManagement</PageTitle>

<div>
    <h3 class="font-bold text-lg">Tasks Management</h3>

    <div class="overflow-x-auto pt-4">
        <table class="table w-full">
            <thead>
            <tr>
                <th>Name</th>
                <th>Cron Expression</th>
                <th>Alarm Level</th>
                <th>Channel</th>
                <th>Status</th>
                <th>Created Time</th>
                <th>Actions</th>
            </tr>
            </thead>
            <tbody>
            @foreach (var taskDto in _taskConfigDtos)
            {
                <tr class="bg-base-200">
                    <td>@taskDto.TaskConfig.Name</td>
                    <td>@taskDto.TaskConfig.CronExpression</td>
                    <td>
                        @if (taskDto.TaskConfig.AlarmLevel == AlarmLevel.None)
                        {
                            <span class="bg-gray-200 text-gray-800 px-2 py-1 rounded">@(taskDto.TaskConfig.AlarmLevel.ToString())</span>
                        }
                        else if (taskDto.TaskConfig.AlarmLevel == AlarmLevel.C)
                        {
                            <span class="bg-warning text-white px-2 py-1 rounded">@(taskDto.TaskConfig.AlarmLevel.ToString())</span>
                        }
                        else if (taskDto.TaskConfig.AlarmLevel == AlarmLevel.D)
                        {
                            <span class="bg-error text-white px-2 py-1 rounded">@(taskDto.TaskConfig.AlarmLevel.ToString())</span>
                        }
                        else
                        {
                            <span class="bg-gray-200 text-gray-800 px-2 py-1 rounded">@(AlarmLevel.None.ToString())</span>
                        }
                    </td>
                    <td>@taskDto.ChannelName</td>
                    <td>
                        @if (taskDto.TaskConfig.Status == VibDataGenerateTaskStatus.Running)
                        {
                        <span class="bg-success text-white px-2 py-1 rounded">Running</span>
                        }
                        else
                        {
                        <span class="bg-error text-white px-2 py-1 rounded">Stopped</span>
                        }
                    </td>
                    <td>@taskDto.TaskConfig.CreatedTime</td>
                    <td>
                        <button class="btn btn-outline btn-primary btn-sm" @onclick="() => ToggleStatusAsync(taskDto.TaskConfig.Id)">Toggle Status</button>
                        <button class="btn btn-outline btn-warning btn-sm ml-2" @onclick="() => EditTask(taskDto.TaskConfig.Id)">Edit</button>
                        <button class="btn btn-outline btn-error btn-sm ml-2" @onclick="() => DeleteTaskAsync(taskDto.TaskConfig.Id)">Delete</button>
                    </td>
                </tr>
            }
            </tbody>
        </table>
    </div>

    <div class="pt-4">
        <h4 class="font-bold text-md">@(_isEditMode ? "Edit Task" : "Add New Task")</h4>
        <div class="pt-4">
            <EditForm Model="@_currentTask" OnValidSubmit="@SaveTaskAsync" FormName="taskmanagement">
                <DataAnnotationsValidator/>
                <ValidationSummary/>

                <div class="form-control">
                    <label for="name" class="label">Name:</label>
                    <InputText id="name" @bind-Value="_currentTask.Name" class="input input-bordered w-full max-w-xs"/>
                    <ValidationMessage For="@(() => _currentTask.Name)" class="text-error"/>
                </div>

                <div class="form-control">
                    <label for="cronExpression" class="label">Cron Expression:</label>
                    <InputText id="cronExpression" @bind-Value="_currentTask.CronExpression" class="input input-bordered w-full max-w-xs"/>
                    <ValidationMessage For="@(() => _currentTask.CronExpression)" class="text-error"/>
                    @if (!string.IsNullOrWhiteSpace(_cronExpressionError))
                    {
                        <div class="text-error">@_cronExpressionError</div>
                    }
                    <a class="link p-1" href="https://www.bejson.com/othertools/cron/" target="_blank">Quartz Cron 表达式生成器</a>
                </div>
                
                @* AlarmLevel *@
                <div class="form-control">
                    <label for="alarmLevel" class="label">Alarm Level:</label>
                    <InputSelect id="alarmLevel" @bind-Value="_selectedAlarmLevel" class="select select-bordered w-full max-w-xs">
                        @foreach (AlarmLevel alarmLevel in Enum.GetValues(typeof(AlarmLevel)))
                        {
                            <option value="@((int)alarmLevel)">@alarmLevel</option>
                        }
                    </InputSelect>
                </div>
                
                <div class="form-control">
                    <label for="channelConfig" class="label">Channel:</label>
                    <InputSelect id="channelConfig" @bind-Value="_selectedChannelId" class="select select-bordered w-full max-w-xs">
                        @foreach (var channel in _channels)
                        {
                            <option value="@channel.Id.ToString()">@channel.Name</option>
                        }
                    </InputSelect>
                    <ValidationMessage For="@(() => _selectedChannelId)" class="text-error"/>
                    @if (!string.IsNullOrWhiteSpace(_selectedChannelIdError))
                    {
                        <div class="text-error">@_selectedChannelIdError</div>
                    }
                </div>

                <button type="submit" class="btn btn-primary mt-4">
                    @(_isEditMode ? "Update Task" : "Add Task")
                </button>
            </EditForm>
        </div>
    </div>
</div>

@code {
    private List<TaskConfigDto> _taskConfigDtos = new();
    private List<ChannelConfig> _channels = new();
    private TaskConfig _currentTask = new();
    private string _selectedChannelId = string.Empty;

    private string _selectedChannelIdError = string.Empty;
    private string _cronExpressionError = string.Empty;
    private bool _isEditMode = false;

    private int _selectedAlarmLevel;

    protected override void OnInitialized()
    {
        LoadChannels();
        LoadTasks();

        ResetForm();
    }

    private void LoadTasks()
    {
        var taskConfigs = TaskConfigRepository.GetAllTasks();
        _taskConfigDtos = taskConfigs.Select(tc =>
        {
            return new TaskConfigDto
            {
                TaskConfig = tc,
                ChannelName = _channels.FirstOrDefault(c => c.Id == tc.ChannelConfigId)?.Name ?? string.Empty
            };
        }).ToList();

        StateHasChanged();
    }

    private void LoadChannels()
    {
        _channels = ChannelRepository.GetAllConfigs();
    }

    private async Task SaveTaskAsync()
    {
        _currentTask.AlarmLevel = (AlarmLevel)_selectedAlarmLevel;
        
        if (string.IsNullOrWhiteSpace(_selectedChannelId))
        {
            _selectedChannelIdError = "Channel is required";
            return;
        }

        _selectedChannelIdError = string.Empty;

        _currentTask.ChannelConfigId = new ObjectId(_selectedChannelId);

        if (!CronExpression.IsValidExpression(_currentTask.CronExpression))
        {
            _cronExpressionError = "Invalid Cron Expression. Please enter a valid Quartz Cron expression.";
            return;
        }

        _cronExpressionError = string.Empty;

        StateHasChanged();

        if (_isEditMode)
        {
            await TaskManagementService.UpdateTaskAsync(_currentTask);
            // TaskConfigRepository.UpdateTask(_currentTask);
        }
        else
        {
            await TaskManagementService.AddTaskAsync(_currentTask);
            // TaskConfigRepository.AddTask(_currentTask);
        }

        LoadTasks();
        ResetForm();
    }

    private void EditTask(ObjectId id)
    {
        var task = TaskConfigRepository.GetTaskById(id);

        _currentTask = task;
        _selectedChannelId = task.ChannelConfigId.ToString();
        _selectedAlarmLevel = (int)task.AlarmLevel;

        _isEditMode = true;
    }

    private async Task ToggleStatusAsync(ObjectId id)
    {
        await TaskManagementService.ToggleStatusAsync(id);
        // TaskConfigRepository.ToggleTaskStatus(id);
        LoadTasks();
    }

    private async Task DeleteTaskAsync(ObjectId id)
    {
        await TaskManagementService.DeleteTaskAsync(id);
        // TaskConfigRepository.DeleteTask(id);
        LoadTasks();
    }

    private void ResetForm()
    {
        _currentTask = new TaskConfig();
        _selectedChannelId = string.Empty;
        _isEditMode = false;
        
        _selectedAlarmLevel = 0;
    }

    public class TaskConfigDto
    {
        public TaskConfig TaskConfig { get; set; } = null!;

        public string ChannelName { get; set; } = null!;
    }

}